/*
 * File:   main.c
 * Author:  Dominik H�ussler
 *          Ruben Schwarz
 *
 * Created on 2. M�rz 2011, 09:30
 *
 * �nderungen:
 * 2011/03/02   Real-Time-Clock implementiert
 *              UART2 f�r DEBUG-Zwecke implementiert
 */

//#include <p33Fxxxx.h>
#include  <p33FJ12MC202.h>
#include <uart.h>

#include <stdlib.h>
#include "sensor_typedefs.h"
#include "communication.h"
#include "hardware_settings.h"
#include "mc.h"


// Select Internal FRC at POR
_FOSCSEL(FNOSC_FRC);

// Enable Clock Switching and Configure
_FOSC(FCKSM_CSECMD & OSCIOFNC_OFF);


_FWDT(FWDTEN_OFF); // Watchdog Timer Enabled/disabled by user software

// Settings for Motor-PWM
_FPOR( HPOL_ON & LPOL_ON );

// Globale Variablen
ESensorAct g_actSensor = NO_SENSOR_ACTIV;
ESystemState g_state = MOTORCONTROL_MODE;
int g_sens4 = 0;
int g_sens4_alarm = 0;
int g_motorSpeed = 0;

void __attribute__((__interrupt__, auto_psv)) _T2Interrupt(void) {
    IEC0bits.T2IE = 0;
    char input = getcUART1();

    if (!DataRdyUART1()) {
        switch (input) {
            case SENSOR_ADDR_0:
                break;
            case SENSOR_ADDR_1:
                break;
            case SENSOR_ADDR_2:
            	sendSensorData(SENSOR_ADDR_2, DATA_REVOLUTION, g_motorSpeed, FALSE);
                break;
            case SENSOR_ADDR_3:
                sendSensorData(SENSOR_ADDR_3, DATA_VOLTAGE, 45, TRUE);
                break;
            case SENSOR_ADDR_4:
                sendSensorData(SENSOR_ADDR_4, DATA_VOLTAGE, g_sens4, g_sens4_alarm);
                break;
            case SENSOR_ADDR_5:
                sendSensorData(SENSOR_ADDR_5, DATA_CURRENT, 183, FALSE);
                break;
            case SENSOR_ADDR_6:
                break;
            case SENSOR_ADDR_7:
                break;
            case SENSOR_ADDR_8:
                break;
            case SENSOR_ADDR_9:
                break;
            case SENSOR_ADDR_10:
                break;
            case SENSOR_ADDR_11:
                break;
            case SENSOR_ADDR_12:
                break;
            case SENSOR_ADDR_13:
                break;
            case SENSOR_ADDR_14:
                break;
            case SENSOR_ADDR_15:
                break;
            case GOTO_CONFIG_MODE:
            	g_state = CONFIGURATION_MODE;
            default: break;
             //TODO: auf Steuersignale reagieren (0x5A - Rücksetzen z.B.)
        }
    }
    //Unbenoetigte Zeichen aus UART-Lesepuffer löschen
    while (DataRdyUART1()) getcUART1();
    IFS0bits.T2IF = 0; //Clear Timer Interrupt Flag
} //ISR Timer2

void __attribute__((__interrupt__, auto_psv)) _U1RXInterrupt(void) {
    //reset timer2 and enable interrupt
    TMR2 = 0;
    IFS0bits.T2IF = 0;
    IEC0bits.T2IE = 1;
    //T2CONbits.TON = 1;
    IFS0bits.U1RXIF = 0; //Flag löschen
}

void __attribute__((__interrupt__, auto_psv)) _CNInterrupt(void) {
		//high
		if(PORTAbits.RA2)
			TMR1 = 0;
		//low
		else
		{
			if(TMR1 < SERVOTIMER_LOWER_LIMIT)
				g_motorSpeed = 0;
			else if(TMR1 > SERVOTIMER_UPPER_LIMIT)
				g_motorSpeed = 500;
			else
				g_motorSpeed =  (5*( TMR1 - SERVOTIMER_LOWER_LIMIT))/(SERVOTIMER_DIFF);
		}

    IFS1bits.CNIF = 0;//Flag löschen
}

int main(void) {
		//Init Peripherie
		initClock();
		initUart();
		initTimer();
		initRemappablePins();
		initChangeNotification();
		InitMC();

    //Loop forever
    while (1) {

    	switch(g_state)
    	{
				case MOTORCONTROL_MODE:
				{
					mcMain();
				}
				case CONFIGURATION_MODE:
				{
					//send "Ready for Configuration"

					//waiting for new configuration data

					//send "new config accepted"
				}
				case FAILSAFE_MODE:
				{
					//safe shutdown - reset?
				}
    	}


    }

    return 0;
}
